package org.jeecg.modules.commu;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.boot.starter.rabbitmq.client.RabbitMqClient;
import org.jeecg.common.base.BaseMap;
import org.jeecg.modules.driver.DriverCommandList;
import org.jeecg.modules.device.Device;

/**
 * @author Gjing
 *
 * 客户端处理器
 **/
@Slf4j
public class NettyClientHandler extends ChannelInboundHandlerAdapter {

    protected RabbitMqClient rabbitMqClient = null;
    protected String connDeviceId = null;

    protected final int TimeOut = 10;
    protected boolean connectedMsg = false;

    public boolean registerRabbitMq(RabbitMqClient client){
        this.rabbitMqClient = client;
        return true;
    }

    public void setDeviceId(String deviceId) {
        this.connDeviceId = deviceId;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端Active .....");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        log.info("客户端收到消息: {}", msg.toString());
        if(!connectedMsg) {
            sendConnected();
            connectedMsg = true;
        }
        if(rabbitMqClient != null){
            BaseMap bm = new BaseMap();
            bm.put("deviceId",connDeviceId);
            bm.put("data",msg);
            rabbitMqClient.sendMessage("devicedata",bm);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
        log.info("客户端exceptionCaught: {}");
        sendDisconnect();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
        log.info("客户端Unreistered: {}");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelInactive();
        log.info("客户端" + connDeviceId + "InActive: {}");
        sendDisconnect();
    }

    /**
     * 断开连接，本地没法直接更新需要通过MQ
     */
    protected void sendDisconnect(){
        if(rabbitMqClient != null){
            BaseMap bm = new BaseMap();
            bm.put("deviceId",connDeviceId);
            bm.put("data", DriverCommandList.D_LOCAL_DISCONNECT + "##1");
            rabbitMqClient.sendMessage("devicedata",bm);
        }
    }

    protected void sendConnected(){
        if(rabbitMqClient != null){
            BaseMap bm = new BaseMap();
            bm.put("deviceId",connDeviceId);
            bm.put("data", DriverCommandList.D_LOCAL_CONNECTED + "##1");
            rabbitMqClient.sendMessage("devicedata",bm);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("已经"+TimeOut+"秒未收到客户端:" +  connDeviceId + "的消息了！");
        if (evt instanceof IdleStateEvent){
            IdleStateEvent event = (IdleStateEvent)evt;
            if (event.state()== IdleState.READER_IDLE){
                //lossConnectCount++;
                //if (lossConnectCount>2){
                //    System.out.println("关闭这个不活跃通道！");
                    ctx.channel().close();
                //}
            }
        }else {
            super.userEventTriggered(ctx,evt);
        }
    }
}
